<?php
/**
 * @author Sergey Dostovalov
 */
require_once 'MarcField.php';
require_once 'MarcSubfield.php';
require_once 'MarcConstants.php';
class MarcDataField extends  MarcField {
    protected $ind1;
    protected $ind2;
    protected $subfields = array();
    /**
     *
     * @param string $tag
     * @param array $subfields array of MarcSubfield objects
     * @param string $ind1 indicator 1 value
     * @param string $ind2 indicator 1 value
     * @exception Exception
     */
    public function  __construct($tag, array $subfields = array(), $ind1 = null, $ind2 = null)
    {
        parent::__construct($tag);
        $this->ind1 = ($ind1 === null or $ind1 === '')? ' ': $ind1[0];
        $this->ind2 = ($ind2 === null or $ind2 === '')? ' ': $ind2[0];

        if (count($subfields) > 0)  $this->addSubfields($subfields);
        /*try {
            if (count($subfields) > 0)  $this->addSubfields($subfields);
        }
        catch (Exception $e){
            throw $e;
        }*/
    }
    public function  __destruct() {
        $this->ind1 = null;
        $this->ind2 = null;
        $this->subfields = null;
    }

    public function delete(){
        $this->__destruct();
    }
    /**
     *
     * @param array $subfields array of MarcSubfield objects
     * @exception Exception
     */
    public function addSubfields(array $subfields)
    {
        foreach($subfields as $subfield){
            if (!($subfield instanceof MarcSubfield)){
                throw new Exception('subfield must be instnce of MarcSubfield');
            }
            $this->subfields[$subfield->getCode()][] = $subfield;
        }
    }
    /**
     *
     * @param MarcSubfield $subfield
     */
    public function addSubfield(MarcSubfield $subfield)
    {
        $this->subfields[$subfield->getCode()][] = $subfield;
    }
    /**
     *
     * @param string $code code of subfield eg 'a'
     * @return array array of MarcSubfields objects
     * @return null if subfield with code not exist
     */
    public function getSubfield($code)
    {
        if (!isset($this->subfields[$code])) return null;
        return $this->subfields[$code];
    }
    /**
     *
     * @param string $code code of subfield eg 'a'
     * @return MarcSubfield MarcSubfields object
     * @return null if subfield with code not exist
     */
    public function getSingleSubfield($code){
        if (!isset($this->subfields[$code])) return null;
        return $this->subfields[$code][0];
    }
    /**
     *
     * @return array array of subfields grouped by code
     * @return null if field no have subfields
     */
    public function getSubfields(){
        if (count($this->subfields) === 0) return null;
        return $this->subfields;
    }
    /**
     *
     * @param int $ind
     * @return string indivator value
     */
    public function getIndicator($ind)
    {
        if ($ind === 1) return ($this->ind1 === null)? ' ': $this->ind1;
        if ($ind === 2) return ($this->ind2 === null)? ' ': $this->ind2;
    }
    /**
     * Delete firs subfield from the group of subfields by code
     * @param string $code delete first subfield from the group by $code
     * @return bool true if subfield was deleted, or false - if not
     */
    public function deleteSingleSubfield($code){
        if(isset($this->subfields[$code]) and count($this->subfields[$code]) > 0){
            array_shift($this->subfields[$code]); //remove first subfield from the groupe
            return true;
        }
        return false;
    }
    /**
     * Delete group of subfields
     * @param string $code
     * @return int number of deleted subfields
     */
    public function deleteSubfield($code){
        if (isset($this->subfields[$code])){
            $count = count($this->subfields[$code]);
            unset($this->subfields[$code]);
            return $count;
        }
        return 0;
    }
    /**
     *
     * @return bool
     */
    public function isEmpty()
    {
        // If $this->subfields is null, we must have deleted it
        if (!$this->subfields) {
            return true;
        }

        // Iterate through the subfields looking for some data
        foreach ($this->subfields as $subfields_group){
            foreach($subfields_group as $subfield){
                // Check if subfield has data
                if ($subfield->isEmpty() === false) {
                    return false;
                }
            }unset($subfield);
        }unset($subfields_group);
        // It is empty
        return true;
    }
    /**
     * Check for the field has a subfield with $code
     * @param string $code
     * @return bool
     */
    public function isHasSubfield($code){
        if(isset($this->subfields[$code])) return true;
        return false;
    }
    /**
     *
     * @param int $ind indicator number 1 or 2
     * @param string $value indicator value
     */
    public function setIndicator($ind, $value)
    {
        if ($ind === 1) $this->ind1 = $value[0];
        if ($ind === 2) $this->ind2 = $value[0];
    }
    /**
     *
     * @return string field tag
     */
    public function getTag()
    {
        return $this->tag;
    }
    /**
     *
     * @param string $toEncoding encoding of raw marc. Default UTF-8
     * @return string raw marc
     */
    public function toRaw($toEncoding = null)
    {
        ksort($this->subfields);
        $subfields = array();
        foreach ($this->subfields as $subfield_group) {
            foreach($subfield_group as $subfield){
                if (!$subfield->isEmpty()) {
                    $subfields[] = $subfield->toRaw($toEncoding);
                }
            }
        }
        return $this->ind1.$this->ind2.implode('', $subfields).MarcConstants::END_OF_FIELD;
    }
    public function __toString()
    {
        ksort($this->subfields);
        $lines = array();
        // Process tag and indicators
        $pre = sprintf('%3s %1s%1s', $this->tag, 
                ($this->ind1 === ' ' or $this->ind1 === null)? '#': $this->ind1,
                ($this->ind2 === ' ' or $this->ind2 === null)? '#': $this->ind2);

        // Process subfields
        foreach ($this->subfields as $subfields_group) {
            foreach($subfields_group as $subfield){
                $lines[] = sprintf('%6s $%1s %s', $pre, $subfield->getCode(), $subfield->getData());
                $pre = '';
            }
        }
        return join("\n", $lines);
    }
}
?>
